package com.fanh.common.util;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.json.JsonHierarchicalStreamDriver;
import com.thoughtworks.xstream.io.json.JsonWriter;
import com.thoughtworks.xstream.io.xml.DomDriver;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;

import java.io.*;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class XStreamUtil {

	/**
	 * 对象转xml字符串
	 * 
	 * @param item
	 * @param alias
	 * @return
	 */
	public static String toXmlStr(String alias, Object item) {
		String xmlStr = "";
		try {
			XStream xstream = new XStream(new DomDriver());
			xstream.alias(alias, item
					.getClass());
			xmlStr = xstream.toXML(item);
			xmlStr = xmlStr.replaceAll("__", "_");
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return xmlStr;
	}

	/**
	 * xml字符串转对象
	 * 
	 * @param
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static <T> T xmlStrToBean(String xmlStr, Class<T> clz, String alias) {
		try {
			XStream xstream = new XStream(new DomDriver());
			xstream.alias(alias, clz);
			xmlStr = xmlStr.replaceAll("_", "__");
			return (T) xstream.fromXML(xmlStr);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
	public static Map doXMLParse(String strxml) throws JDOMException, IOException {
        strxml = strxml.replaceFirst("encoding=\".*\"", "encoding=\"UTF-8\"");  
  
        if(null == strxml || "".equals(strxml)) {  
            return null;  
        }  
          
        Map m = new HashMap();
          
        InputStream in = new ByteArrayInputStream(strxml.getBytes("UTF-8"));
        SAXBuilder builder = new SAXBuilder();  
        Document doc = builder.build(in);  
        Element root = doc.getRootElement();  
        List list = root.getChildren();
        Iterator it = list.iterator();
        while(it.hasNext()) {  
            Element e = (Element) it.next();  
            String k = e.getName();
            String v = "";
            List children = e.getChildren();
            if(children.isEmpty()) {  
                v = e.getTextNormalize();  
            } else {  
                v = XStreamUtil.getChildrenText(children);  
            }  
              
            m.put(k, v);  
        }  
          
        //关闭流  
        in.close();  
          
        return m;  
    }  
      
    /** 
     * 获取子结点的xml 
     * @param children 
     * @return String 
     */  
    public static String getChildrenText(List children) {
        StringBuffer sb = new StringBuffer();
        if(!children.isEmpty()) {  
            Iterator it = children.iterator();
            while(it.hasNext()) {  
                Element e = (Element) it.next();  
                String name = e.getName();
                String value = e.getTextNormalize();
                List list = e.getChildren();
                sb.append("<" + name + ">");  
                if(!list.isEmpty()) {  
                    sb.append(XStreamUtil.getChildrenText(list));  
                }  
                sb.append(value);  
                sb.append("</" + name + ">");  
            }  
        }  
          
        return sb.toString();  
    }

	public static <T>T toBean(String filePath, Class<T> clz) {
		try {
			File file = new File(filePath);
			FileInputStream fis;
			fis = new FileInputStream(file);
			return XStreamUtil.toBean(fis,clz);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	@SuppressWarnings({ "unchecked" })
	public static<T>T toBean(InputStream is, Class<T> clz){
		XStream xstream = new XStream(new DomDriver());
		xstream.alias(clz.getName().toLowerCase(), clz);
		InputStreamReader reader = new InputStreamReader(is, Charset
				.forName("UTF-8"));
		return (T) xstream.fromXML(reader);
	}
	
	public static<T>void toFile(T obj, String filePath){
		try {
			FileOutputStream fos;
			fos = new FileOutputStream(new File(filePath));
			XStreamUtil.toFile(obj, fos);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
	}

	private static <T> void toFile(T obj, OutputStream os) {
		XStream xstream = new XStream(new DomDriver());
		xstream.alias(obj.getClass().getName().toLowerCase(), obj.getClass());
		OutputStreamWriter writer = new OutputStreamWriter(os, Charset.forName("UTF-8"));
		xstream.toXML(obj, writer);
	}
	
	public static <T> String toZtreeJsonStr(List<T> lst){
		XStream xStream = new XStream(new JsonHierarchicalStreamDriver() {
	        public HierarchicalStreamWriter createWriter(Writer out) {
	            return new JsonWriter(out, JsonWriter.DROP_ROOT_MODE);
	        }
	    });
		xStream.aliasAttribute("code", "id");
		xStream.aliasAttribute("label", "name");
		xStream.aliasAttribute("units", "nodes");
		xStream.aliasAttribute("dictionaries", "nodes");
		xStream.setMode(XStream.NO_REFERENCES);
		String xml = xStream.toXML(lst);
		return xml;
	}
	
}
